package com.wbtech.ums.performance;

import java.util.ArrayList;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import com.wbtech.ums.CobubLog;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.PixelFormat;
import android.os.Binder;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.Toast;

/**
 * FpsService shows fps details at left/top corner, and save the fps file to
 * /mnt/sdcard/fps/yyyyMMdd_HH_mm_ss.fps
 * 
 * @author yuankai02@baidu.com
 * @version 1.0
 * @date 2013-11-14
 */
public class FpsService extends Service implements OnClickListener,
		FpsView.FpsUpdateListener {
	private final static String TAG = "FpsService";

	private ViewGroup mLayout = null;
	private FpsView mFpsView = null;
	private Button mStartBtn = null;
	private Button mStopBtn = null;

	private final static int FPS_VIEW_ID = 1;
	private final static int START_BTN_ID = 2;
	private final static int STOP_BTN_ID = 3;

	private WindowManager windowManager;
	private WindowManager.LayoutParams layoutParams;
	private RelativeLayout.LayoutParams rlp;

	private float mTouchStartX;
	private float mTouchStartY;
	private float x;
	private float y;
	private int count = 0; // 通过次数统计fps经历的时间
	private static final int MAXCOUNT = 1500; // 最多统计5分钟的fps数据

	private BlockingQueue<ArrayList<FpsRecord>> mRecordQueue = new LinkedBlockingQueue<ArrayList<FpsRecord>>();
	private ArrayList<FpsRecord> mCurrentRecords = null;
	private FpsWorker mWorker = null;
	private ServiceBinder serviceBinder = new ServiceBinder();;

	private Runnable mInvalidateRunnable = new Runnable() {
		@Override
		public void run() {
			if (mLayout != null) {
				mLayout.invalidate();
				mLayout.post(this);
			}
		}
	};

	@Override
	public void onCreate() {
		CobubLog.i(TAG, "onCreate");
		super.onCreate();
		windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
		layoutParams = new WindowManager.LayoutParams();
		showFpsOnScreen();
	}

	/*
	 * @Override public int onStartCommand(Intent intent, int flags, int
	 * startId) { CobubLog.i(TAG, "onStartCommand"); return START_STICKY; }
	 */

	private void showFpsOnScreen() {

		layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; // 设置window
																			// type

		// //下面的flags属性的效果相当于“锁定”。悬浮窗不可触摸，不接受任何事件，同时不影响后面的事件响应。
		// layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
		// WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
		// WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

		layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
				| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // 设置window
																	// flag
		layoutParams.format = PixelFormat.RGBA_8888; // 设置背景为透明
		layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
		layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
		layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
		layoutParams.x = 0;
		layoutParams.y = 0;
		// myLayout is the customized layout which contains textview
		mLayout = new RelativeLayout(this);
		rlp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT);
		mFpsView = new FpsView(this);
		mFpsView.setId(FPS_VIEW_ID);
		mFpsView.setListener(this);
		mLayout.addView(mFpsView, rlp);

		rlp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT);
		rlp.addRule(RelativeLayout.BELOW, FPS_VIEW_ID);
		mStartBtn = new Button(this);
		mStartBtn.setId(START_BTN_ID);
		mStartBtn.setText("start");
		mStartBtn.setOnClickListener(this);
		mLayout.addView(mStartBtn, rlp);

		rlp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT);
		rlp.addRule(RelativeLayout.BELOW, START_BTN_ID);
		mStopBtn = new Button(this);
		mStopBtn.setId(STOP_BTN_ID);
		mStopBtn.setText("stop");
		mStopBtn.setOnClickListener(this);
		mLayout.addView(mStopBtn, rlp);

		mLayout.post(mInvalidateRunnable);
		mLayout.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				// TODO Auto-generated method stub

				// 获取相对屏幕的坐标，即以屏幕左上角为原点
				x = event.getRawX();
				y = event.getRawY();
				Log.i("FpsView", "x=" + x + ";y=" + y);

				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					Log.i("FpsView", "ACTION_DOWN");
					// 获取相对view的坐标，即以此view左上角为原点
					mTouchStartX = event.getX();
					mTouchStartY = event.getY();
					Log.i("FpsView", "mTouchStartX=" + mTouchStartX
							+ ";mTouchStartY=" + mTouchStartY);

					break;
				case MotionEvent.ACTION_MOVE:
					Log.i("FpsView", "ACTION_MOVE");
					updateViewPosition();
					break;
				case MotionEvent.ACTION_UP:
					Log.i("FpsView", "ACTION_UP");
					updateViewPosition();
					mTouchStartX = mTouchStartY = 0;
					break;
				default:
					break;
				}

				return false;
			}
		});

		windowManager.addView(mLayout, layoutParams);

		mStartBtn.setEnabled(true);
		mStopBtn.setEnabled(false);

		mWorker = new FpsWorker(getApplicationContext(), mRecordQueue);
		mWorker.start();
	}

	private void updateViewPosition() {
		// 更新浮动窗口位置参数
		layoutParams.x = (int) (x - mTouchStartX);
		layoutParams.y = (int) (y - mTouchStartY);
		Log.i("FpsView", "LayoutParams.x=" + layoutParams.x
				+ ";LayoutParams.y=" + layoutParams.y);
		windowManager.updateViewLayout(mLayout, layoutParams);
	}

	@Override
	public IBinder onBind(Intent intent) {
		CobubLog.i(TAG, "on bind");
		return serviceBinder;
		// return null;
	}

	@Override
	public void unbindService(ServiceConnection conn) {
		// TODO Auto-generated method stub
		CobubLog.i(TAG, "unbind");
		super.unbindService(conn);
	}

	@Override
	public void onDestroy() {
		CobubLog.i(TAG, "onDestroy");
		super.onDestroy();
		if (mLayout != null && mLayout.getParent() != null) {
			WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
			windowManager.removeView(mLayout);
			mLayout.removeAllViews();
		}
		mFpsView = null;
		mStartBtn = null;
		mStopBtn = null;
		if (mWorker != null) {
			mWorker.quit();
			mWorker = null;
		}
		serviceBinder = null;
	}

	@Override
	public void onClick(View v) {
		final int id = v.getId();
		if (id == START_BTN_ID) {
			// start record
			if (Environment.getExternalStorageState().equals(
					Environment.MEDIA_MOUNTED)) {
				mStartBtn.setEnabled(false);
				mStopBtn.setEnabled(true);
				mCurrentRecords = new ArrayList<FpsRecord>(1500); // record for
																	// 5min
			} else {
				Toast.makeText(getApplicationContext(),
						"sd card is unavailable！", Toast.LENGTH_LONG).show();
			}
		} else if (id == STOP_BTN_ID) {
			// stop record and save to file
			mStartBtn.setEnabled(true);
			mStopBtn.setEnabled(false);

			mRecordQueue.add(mCurrentRecords);
			mCurrentRecords = null;
			count = 0;
		}
	}

	@Override
	public void onUpdateFps(double fps, long frameCount, long realTime) {
		if (mStartBtn.isEnabled())
			return;
		if (count <= MAXCOUNT) {
			mCurrentRecords.add(new FpsRecord(fps, frameCount, realTime));
			count++;
		}
	}

	// 此方法是为了可以在调用处获取服务的实例
	public class ServiceBinder extends Binder {
		public FpsService getService() {
			return FpsService.this;
		}
	}

}
